package net.topikachu.dynamic.faces;

import java.io.IOException;

import javax.el.ELException;
import javax.el.VariableMapper;
import javax.faces.FacesException;
import javax.faces.component.UIComponent;

import net.topikachu.dynamci.exception.DynamicException;
import net.topikachu.dynamic.screen.widget.Widget;

import com.sun.facelets.FaceletContext;
import com.sun.facelets.FaceletException;
import com.sun.facelets.el.VariableMapperWrapper;
import com.sun.facelets.tag.TagAttribute;
import com.sun.facelets.tag.TagConfig;
import com.sun.facelets.tag.TagHandler;

public class ScreenHandler extends TagHandler {
	private TagAttribute widgetTag;
	private TagAttribute[] vars;

	public ScreenHandler(TagConfig config) {
		super(config);
		this.widgetTag = this.tag.getAttributes().get("widget");
		this.vars = this.tag.getAttributes().getAll();

	}

	public void apply(FaceletContext ctx, UIComponent parent)
			throws IOException, FacesException, FaceletException, ELException {

		if (widgetTag == null) {
			throw new DynamicException("No widget attribute defined.");
		}
		Widget widget = (Widget) widgetTag.getObject(ctx, Widget.class);

		VariableMapper orig = ctx.getVariableMapper();
		if (this.vars.length > 0) {
			VariableMapper varMapper = new VariableMapperWrapper(orig);
			for (int i = 0; i < this.vars.length; i++) {
				if (vars[i].getLocalName().equals("widget")) {
					continue;
				}
				varMapper.setVariable(this.vars[i].getLocalName(), this.vars[i]
						.getValueExpression(ctx, Object.class));
			}
			ctx.setVariableMapper(varMapper);
		}
		try {
			WidgetPlaceHolderStack.createStack(ctx);
			widget.apply(ctx, parent);

		} finally {
			WidgetPlaceHolderStack.removeStack(ctx);
			ctx.setVariableMapper(orig);
		}
	}

}
